package cloud.lysky.java.on.concurrent.queue;

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * @author luoly
 * @describe DelayQueue使用示例
 * @date 2023-05-01 11:09
 **/
// 在实现一个延迟订单的场景中，我们可以定义一个 Order 类，其中包含订单的基本信息，
// 例如订单编号、订单金额、订单创建时间等。同时，我们可以让 Order 类实现 Delayed 接口，
// 重写 getDelay 和compareTo 方法。在 getDelay 方法中，我们可以计算订单的剩余延迟时间，
// 而在 compareTo 方法中，我们可以根据订单的延迟时间进行比较。
// 下面是一个简单的示例代码，演示了如何使用 DelayQueue 来实现一个延迟订单的场景：
public class DelayQueueExample implements Delayed {
    private String orderId; //订单编号
    private long orderTime; //订单创建时间
    private long delayTime; //订单延迟时间

    public DelayQueueExample(String orderId, long orderTime, long delayTime) {
        this.orderId = orderId;
        this.orderTime = orderTime;
        this.delayTime = delayTime;
    }

    @Override
    public long getDelay(TimeUnit unit) {
        // 计算剩余延迟时间
        long diff = orderTime + delayTime - System.currentTimeMillis();
        return unit.convert(diff, TimeUnit.MILLISECONDS);
    }

    @Override
    public int compareTo(Delayed o) {
        // 比较延迟时间
        long diff = this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS);
        return Long.compare(diff, 0);
    }

    @Override
    public String toString() {
        return "order{" +
                "orderId='" + orderId + '\'' +
                ", orderTime=" + orderTime +
                ", delayTime=" + delayTime +
                '}';
    }

    public static void main(String[] args) {
        DelayQueue<DelayQueueExample> delayQueue = new DelayQueue<>();
        // 创建3个订单，延迟时间依次为5s、15s、10s
        DelayQueueExample order1 = new DelayQueueExample("1", System.currentTimeMillis(), 5000);
        DelayQueueExample order2 = new DelayQueueExample("2", System.currentTimeMillis(), 15000);
        DelayQueueExample order3 = new DelayQueueExample("3", System.currentTimeMillis(), 10000);
        // 将订单放入延迟队列中
        delayQueue.put(order1);
        delayQueue.put(order2);
        delayQueue.put(order3);
        // 启动一个线程从延迟队列中取订单
        new Thread(() -> {
            while (true) {
                try {
                    // 从延迟队列中取出订单
                    DelayQueueExample order = delayQueue.take();
                    System.out.println("订单" + order.orderId + "已完成，完成时间：" + System.currentTimeMillis());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}
